/*
 * Copyright (C) 2021 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package me.panpf.sketch.sample.widget.fraction;

import me.panpf.sketch.Sketch;
import me.panpf.sketch.cache.BitmapPoolUtils;
import me.panpf.sketch.sample.AssetImage;
import me.panpf.sketch.sample.ResourceTable;
import me.panpf.sketch.util.SketchUtils;
import me.panpf.sketch.util.Utils;
import me.panpf.sketch.zoom.PixmapBuild;
import ohos.aafwk.ability.fraction.Fraction;
import ohos.aafwk.content.Intent;
import ohos.agp.components.*;
import ohos.agp.components.element.ShapeElement;
import ohos.agp.utils.Color;
import ohos.media.image.ImageSource;
import ohos.media.image.PixelMap;
import ohos.media.image.common.ImageInfo;
import ohos.media.image.common.PixelFormat;
import ohos.media.image.common.Rect;
import ohos.media.image.common.Size;

import java.util.Locale;

/**
 * InBitmapTestFraction
 */
public class InBitmapTestFraction extends Fraction implements Component.ClickedListener {
    private Image imageView;
    private Text textView;
    private Button sizeSameButton;
    private Button largeSizeButton;
    private Button sizeNoSameButton;
    private Button inSampleSizeButton;
    private Text pageNumberTextView;
    private Component lastView;
    private Component nextView;

    private int index = 0;
    private Button currentMode;

    private StringBuilder mBuilder;
    private String mFilePath;

    private boolean mIsAutoClick = false;

    @Override
    protected Component onComponentAttached(LayoutScatter scatter, ComponentContainer container, Intent intent) {
        Component component = scatter.parse(ResourceTable.Layout_in_bitmap_test_fraction, container, false);
        return component;
    }

    @Override
    protected void onStart(Intent intent) {
        super.onStart(intent);
        index = 0;
        initComponent();
        initListener();
    }

    private void initComponent() {
        imageView = (Image) getComponent().findComponentById(ResourceTable.Id_image_inBitmapTest);
        textView = (Text) getComponent().findComponentById(ResourceTable.Id_text_inBitmapTest);
        sizeSameButton = (Button) getComponent().findComponentById(ResourceTable.Id_button_inBitmapTest_sizeSame);
        largeSizeButton = (Button) getComponent().findComponentById(ResourceTable.Id_button_inBitmapTest_largeSize);
        sizeNoSameButton = (Button) getComponent().findComponentById(ResourceTable.Id_button_inBitmapTest_sizeNoSame);
        inSampleSizeButton = (Button) getComponent().findComponentById(ResourceTable.Id_button_inBitmapTest_inSampleSize);
        pageNumberTextView = (Text) getComponent().findComponentById(ResourceTable.Id_text_inBitmapTest_pageNumber);
        lastView = getComponent().findComponentById(ResourceTable.Id_view_inBitmapTest_last);
        nextView = getComponent().findComponentById(ResourceTable.Id_view_inBitmapTest_next);

        imageView.setScaleMode(Image.ScaleMode.STRETCH);
    }

    private void initListener() {
        lastView.setClickedListener(this::onClick);
        nextView.setClickedListener(this::onClick);

        sizeSameButton.setClickedListener(this::onClick);
        largeSizeButton.setClickedListener(this::onClick);
        sizeNoSameButton.setClickedListener(this::onClick);
        inSampleSizeButton.setClickedListener(this::onClick);

        sizeSameButton.simulateClick();

    }

    private void updateCheckedStatus(Button newView) {
        if (currentMode != null) {
            currentMode.setTextColor(new Color(getFractionAbility().getColor(ResourceTable.Color_black)));
            currentMode.setBackground(new ShapeElement(getFractionAbility(), ResourceTable.Graphic_button_element_normal));
        }

        newView.setBackground(new ShapeElement(getFractionAbility(), ResourceTable.Graphic_button_element_pressed));
        newView.setTextColor(new Color(getFractionAbility().getColor(ResourceTable.Color_text_disable)));
        currentMode = newView;

        pageNumberTextView.setText(String.format("%d/%d", index + 1, AssetImage.IN_BITMAP_SAMPLES.length, Locale.ENGLISH));
    }

    private void testSize() {
        mFilePath = AssetImage.IN_BITMAP_SAMPLES[index % AssetImage.IN_BITMAP_SAMPLES.length];
        ImageSource imageSource = Utils.getImageSource(getFractionAbility(), mFilePath);

        PixelMap pixelMap = imageSource.createPixelmap(null);
        ImageSource.DecodingOptions decodingOpts = new ImageSource.DecodingOptions();
        decodingOpts.desiredRegion = new Rect(0, 0, 0, 0);
        decodingOpts.desiredPixelFormat = PixelFormat.ARGB_8888;
        decodingOpts.sampleSize = currentMode == inSampleSizeButton ? 2 : 1;

        if (currentMode == largeSizeButton) {
            Size size = pixelMap.getImageInfo().size;
            decodingOpts.desiredSize = new Size(size.width + 10, size.height + 5);
        }

        decodingOpts.editable = true;
        PixelMap inPixelMap = imageSource.createPixelmap(decodingOpts);

        ImageInfo imageInfo = inPixelMap.getImageInfo();
        int inWidth = imageInfo.size.width;
        int inHeight = imageInfo.size.height;

        mBuilder = new StringBuilder();
        mBuilder.append("imageUri: ").append(mFilePath);
        int width = pixelMap.getImageInfo().size.width;
        int height = pixelMap.getImageInfo().size.height;

        Double aspectRatios = width / (double) height;
        imageView.setWidth(Utils.getDisplayWidthInPx(getFractionAbility()));
        imageView.setHeight((int) (imageView.getWidth() / aspectRatios));
        imageView.setPixelMap(currentMode == inSampleSizeButton ? inPixelMap : pixelMap);
        PixmapBuild pixmapBuild = new PixmapBuild(imageSource);

        if (!BitmapPoolUtils.freeBitmapToPool(pixmapBuild, Sketch.with(getFractionAbility()).getConfiguration().getBitmapPool())) {

        }
        int sizeInBytes = SketchUtils.computeByteCount(width, height, null);
        String huanHang = getFractionAbility().getString(ResourceTable.String_huanhang);
        mBuilder.append(huanHang).append("image: ")
                .append(width).append("x").append(height)
                .append(", ").append(decodingOpts.desiredPixelFormat.toString())
                .append(", ").append(sizeInBytes);

        mBuilder.append("huanHang").append("inSampleSize: ").append(decodingOpts.sampleSize);

        mBuilder.append("huanHang")
                .append("inBitmap: ")
                .append(Integer.toHexString(inPixelMap.hashCode()))
                .append(", ").append(currentMode == sizeNoSameButton ? inHeight : inWidth).append("x")
                .append(currentMode == sizeNoSameButton ? inWidth : inHeight)
                .append(", ").append(decodingOpts.editable)
                .append(", ").append(inPixelMap.getPixelBytesCapacity());

        mBuilder.append("huanHang").append("newBitmap: ")
                .append(Integer.toHexString(inPixelMap.hashCode()))
                .append(", ").append(inWidth).append("x").append(inHeight)
                .append(", ").append(decodingOpts.editable)
                .append(", ").append(inPixelMap.getPixelBytesCapacity());

        textView.setText(mBuilder.toString());
    }

    @Override
    public void onClick(Component component) {
        switch (component.getId()) {
            case ResourceTable.Id_view_inBitmapTest_last:
                mIsAutoClick = true;
                --index;
                if (index < 0) {
                    index = AssetImage.IN_BITMAP_SAMPLES.length - Math.abs(index);
                }
                currentMode.simulateClick();
                break;
            case ResourceTable.Id_view_inBitmapTest_next:
                mIsAutoClick = true;
                index = ++index % AssetImage.IN_BITMAP_SAMPLES.length;
                currentMode.simulateClick();
                break;
            case ResourceTable.Id_button_inBitmapTest_sizeSame:
            case ResourceTable.Id_button_inBitmapTest_largeSize:
            case ResourceTable.Id_button_inBitmapTest_sizeNoSame:
            case ResourceTable.Id_button_inBitmapTest_inSampleSize:
                if (!mIsAutoClick) {
                    if (currentMode == component) {
                        return;
                    }
                }
                updateCheckedStatus((Button) component);
                testSize();
                mIsAutoClick = false;
                break;
            default:
                break;
        }
    }
}
